package com.anche.demo.service;

import com.alibaba.excel.EasyExcel;
import com.anche.demo.entity.User;
import com.anche.demo.listener.UserListener;
import com.anche.demo.mapper.UserMapper;
import com.anche.demo.service.impl.UserService;
import com.anche.demo.util.HttpUtils;
import com.anche.demo.util.ThreadPoolExcuteUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @Classname UserService
 * @Description TODO
 * @Date 2022/11/27 12:33
 * @Created by Administrator
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
    @Resource
    UserMapper userMapper;

    @Resource
    RedissonClient redissonClient;
    @Autowired
    ApplicationContext applicationContext;
    /**
     * 如果用user1作为入参会存在重复数据
     * @param user1
     */
    @Override
    public void saves(User user1) {
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            User uesr = new User();
            uesr.setAge(String.valueOf(i));
            uesr.setName("测试" + i);
            users.add(uesr);
        }
        users.forEach(obj -> ThreadPoolExcuteUtil.executor.execute(() -> {
            User user=new User();
            user.setName(obj.getName());
            user.setAge(obj.getAge());
            RLock lock = redissonClient.getLock(user.getName());
            try {
                UserServiceImpl userService=  (UserServiceImpl)AopContext.currentProxy();
                userService.update(user);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }));

    }

    @Override
    @Async
    public void upload(MultipartFile file) {
        try {
            UserService userService = applicationContext.getBean(UserService.class);
            EasyExcel.read(file.getInputStream(), User.class,new UserListener(userService)).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("下载文件");
    }

    @Transactional(rollbackFor = Exception.class)
    public int update(User user) throws InterruptedException {
        log.info("thread{}", Thread.currentThread().getName());
        RLock lock = redissonClient.getLock(user.getName());
        boolean tryLock = lock.tryLock(10, 30, TimeUnit.SECONDS);
        if(!tryLock){
            log.info("加锁失败"+user.getName());
            return 0;
        }else {
            log.info("加锁成功"+user.getName());
            lock.lock();
            Thread.sleep(10);
        }
        try {
            QueryWrapper<User> select = new QueryWrapper<>();
            select.eq("name", user.getName());
            List<User> ls = userMapper.selectList(select);
            if (ls.size() > 0) {
                log.info("已存在");
            } else {
                userMapper.insert(user);
            }
        } catch (Exception e) {
            log.error("修改失败{}", e);
            throw new RuntimeException("失败");
        }
        return 2;
    }
    @Override
    public void httpConvert() {
        HttpUtils.postByFrom();
    }
}